package com.dt.core.tool.util;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Array;
import java.net.URL;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;

import com.dt.core.tool.enums.OsType;
import com.dt.core.tool.util.support.StrKit;

/**
 * 高频方法集合类
 */
public class ToolUtil {
	/*
	 * 均衡的随机从[mix,max]中获取数据
	 */
	public static int rand(int mix, int max) {
		return RandomUtil.rand(mix, max);
	}

	public static String getUUID() {
		UUID uuid = UUID.randomUUID();
		String str = uuid.toString();
		str = str.replaceAll("-", "");
		return str;
	}

	public static void printRequestMap(HttpServletRequest request) {
		System.out.println("###################requst map#########################");
		Map<String, String[]> map = request.getParameterMap();
		System.out.println("url:" + request.getLocalAddr() + ":" + request.getLocalPort() + request.getRequestURI()
				+ (map.size() > 0 ? "?" + request.getQueryString() : ""));
		System.out.println("uri:" + request.getRequestURI());
		System.out.println("addr:" + request.getLocalAddr());
		System.out.println("query:" + request.getQueryString());
		System.out.println("#####query####");
		for (String key : map.keySet()) {
			String values = "";
			for (int i = 0; i < map.get(key).length; i++) {
				values = map.get(key)[i] + " ## ";
			}
			System.out.println(key + ":" + values);
		}
		System.out.println("###################requst end#########################");
	}

	@SuppressWarnings("rawtypes")
	public static String get(Class cls) {
		String strURL = "";
		try {
			String strClassName = cls.getName();
			String strPackageName = "";
			if (cls.getPackage() != null) {
				strPackageName = cls.getPackage().getName();
			}
			String strClassFileName = "";
			if (!"".equals(strPackageName)) {
				strClassFileName = strClassName.substring(strPackageName.length() + 1, strClassName.length());
			} else {
				strClassFileName = strClassName;
			}
			URL url = null;
			url = cls.getResource(strClassFileName + ".class");
			strURL = url.toString();
			strURL = strURL.substring(strURL.indexOf('/') + 1, strURL.lastIndexOf('/'));
			try {
				strURL = java.net.URLDecoder.decode(strURL, "UTF-8");
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			}
			OsType os = OsType.getOSType();
			if (os == OsType.Windows) {
			} else if (os == OsType.Linux) {
				strURL = "/" + strURL;
			} else {
				strURL = "/" + strURL;
			}
		} catch (Exception c) {
		}
		return strURL;
	}

	public static String getRealPathInWebApp(String relativePath) {
		String path = get(ToolUtil.class);
		path = path.substring(0, path.indexOf("/WEB-INF/"));
		return path + "/" + relativePath;
	}

	public static String parseYNValue(String value) {
		if (value == null) {
			return value;
		}
		if (value.equals("Y")) {
			return "Y";
		}
		if (value.equals("N")) {
			return "N";
		}
		return value;
	}

	public static String parseYNValueDefN(String value) {
		if (value == null) {
			return "N";
		}
		if (value.equals("Y")) {
			return "Y";
		}
		if (value.equals("N")) {
			return "N";
		}
		return "N";
	}

	public static String parseYNValueDefY(String value) {
		if (value == null) {
			return "Y";
		}
		if (value.equals("Y")) {
			return "Y";
		}
		if (value.equals("N")) {
			return "N";
		}
		return "Y";
	}

	public static String getExceptionMsg(Exception e) {
		StringWriter sw = new StringWriter();
		try {
			e.printStackTrace(new PrintWriter(sw));
		} finally {
			try {
				sw.close();
			} catch (IOException e1) {
				e1.printStackTrace();
			}
		}
		return sw.getBuffer().toString().replaceAll("\\$", "T");
	}

	/**
	 * @Description 随机数字
	 * @author fengshuonan
	 */
	public static String getRandomNum() {
		return Calendar.getInstance().getTimeInMillis() + generateCellPhoneValNum();
	}

	/**
	 * @Description 获取电话号码
	 * @author fengshuonan
	 */
	public static String generateCellPhoneValNum() {
		String[] beforeShuffle = new String[] { "1", "2", "3", "4", "5", "6", "7", "8", "9", "0" };
		List<String> list = Arrays.asList(beforeShuffle);
		Collections.shuffle(list);
		StringBuilder buffer = new StringBuilder();
		for (int i = 0; i < list.size(); i++) {
			buffer.append(list.get(i));
		}
		String afterShuffle = buffer.toString();
		String result = afterShuffle.substring(3, 9);
		return result;
	}

	/**
	 * 比较两个对象是否相等。<br>
	 * 相同的条件有两个，满足其一即可：<br>
	 * 1. obj1 == null && obj2 == null; 2. obj1.equals(obj2)
	 * 
	 * @param obj1
	 *            对象1
	 * @param obj2
	 *            对象2
	 * @return 是否相等
	 */
	public static boolean equals(Object obj1, Object obj2) {
		return (obj1 != null) ? (obj1.equals(obj2)) : (obj2 == null);
	}

	/**
	 * 计算对象长度，如果是字符串调用其length函数，集合类调用其size函数，数组调用其length属性，其他可遍历对象遍历计算长度
	 * 
	 * @param obj
	 *            被计算长度的对象
	 * @return 长度
	 */
	public static int length(Object obj) {
		if (obj == null) {
			return 0;
		}
		if (obj instanceof CharSequence) {
			return ((CharSequence) obj).length();
		}
		if (obj instanceof Collection) {
			return ((Collection<?>) obj).size();
		}
		if (obj instanceof Map) {
			return ((Map<?, ?>) obj).size();
		}
		int count;
		if (obj instanceof Iterator) {
			Iterator<?> iter = (Iterator<?>) obj;
			count = 0;
			while (iter.hasNext()) {
				count++;
				iter.next();
			}
			return count;
		}
		if (obj instanceof Enumeration) {
			Enumeration<?> enumeration = (Enumeration<?>) obj;
			count = 0;
			while (enumeration.hasMoreElements()) {
				count++;
				enumeration.nextElement();
			}
			return count;
		}
		if (obj.getClass().isArray() == true) {
			return Array.getLength(obj);
		}
		return -1;
	}

	/**
	 * 对象中是否包含元素
	 * 
	 * @param obj
	 *            对象
	 * @param element
	 *            元素
	 * @return 是否包含
	 */
	public static boolean contains(Object obj, Object element) {
		if (obj == null) {
			return false;
		}
		if (obj instanceof String) {
			if (element == null) {
				return false;
			}
			return ((String) obj).contains(element.toString());
		}
		if (obj instanceof Collection) {
			return ((Collection<?>) obj).contains(element);
		}
		if (obj instanceof Map) {
			return ((Map<?, ?>) obj).values().contains(element);
		}
		if (obj instanceof Iterator) {
			Iterator<?> iter = (Iterator<?>) obj;
			while (iter.hasNext()) {
				Object o = iter.next();
				if (equals(o, element)) {
					return true;
				}
			}
			return false;
		}
		if (obj instanceof Enumeration) {
			Enumeration<?> enumeration = (Enumeration<?>) obj;
			while (enumeration.hasMoreElements()) {
				Object o = enumeration.nextElement();
				if (equals(o, element)) {
					return true;
				}
			}
			return false;
		}
		if (obj.getClass().isArray() == true) {
			int len = Array.getLength(obj);
			for (int i = 0; i < len; i++) {
				Object o = Array.get(obj, i);
				if (equals(o, element)) {
					return true;
				}
			}
		}
		return false;
	}

	/**
	 * 对象是否不为空(新增)
	 * 
	 * @param obj
	 *            String,List,Map,Object[],int[],long[]
	 * @return
	 */
	public static boolean isNotEmpty(Object o) {
		return !isEmpty(o);
	}

	/**
	 * 对象是否为空
	 * 
	 * @param obj
	 *            String,List,Map,Object[],int[],long[]
	 * @return
	 */
	@SuppressWarnings("rawtypes")
	public static boolean isEmpty(Object o) {
		if (o == null) {
			return true;
		}
		if (o instanceof String) {
			if (o.toString().trim().equals("") || o.toString().length() == 0) {
				return true;
			}
		} else if (o instanceof List) {
			if (((List) o).size() == 0) {
				return true;
			}
		} else if (o instanceof Map) {
			if (((Map) o).size() == 0) {
				return true;
			}
		} else if (o instanceof Set) {
			if (((Set) o).size() == 0) {
				return true;
			}
		} else if (o instanceof Object[]) {
			if (((Object[]) o).length == 0) {
				return true;
			}
		} else if (o instanceof int[]) {
			if (((int[]) o).length == 0) {
				return true;
			}
		} else if (o instanceof long[]) {
			if (((long[]) o).length == 0) {
				return true;
			}
		}
		return false;
	}

	/**
	 * 对象组中是否存在 Empty Object
	 * 
	 * @param os
	 *            对象组
	 * @return
	 */
	public static boolean isOneEmpty(Object... os) {
		for (Object o : os) {
			if (isEmpty(o)) {
				return true;
			}
		}
		return false;
	}

	/**
	 * 对象组中是否全是 Empty Object
	 * 
	 * @param os
	 * @return
	 */
	public static boolean isAllEmpty(Object... os) {
		for (Object o : os) {
			if (!isEmpty(o)) {
				return false;
			}
		}
		return true;
	}

	/**
	 * 是否为数字
	 * 
	 * @param obj
	 * @return
	 */
	public static boolean isNum(Object obj) {
		try {
			Integer.parseInt(obj.toString());
		} catch (Exception e) {
			return false;
		}
		return true;
	}

	/**
	 * 如果为空, 则调用默认值
	 * 
	 * @param str
	 * @return
	 */
	public static Object getValue(Object str, Object defaultValue) {
		if (isEmpty(str)) {
			return defaultValue;
		}
		return str;
	}

	/**
	 * 格式化文本
	 * 
	 * @param template
	 *            文本模板，被替换的部分用 {} 表示
	 * @param values
	 *            参数值
	 * @return 格式化后的文本
	 */
	public static String format(String template, Object... values) {
		return StrKit.format(template, values);
	}

	/**
	 * 格式化文本
	 * 
	 * @param template
	 *            文本模板，被替换的部分用 {key} 表示
	 * @param map
	 *            参数值对
	 * @return 格式化后的文本
	 */
	public static String format(String template, Map<?, ?> map) {
		return StrKit.format(template, map);
	}

	/**
	 * 强转->string,并去掉多余空格
	 * 
	 * @param str
	 * @return
	 */
	public static String toStr(Object str) {
		return toStr(str, "");
	}

	/**
	 * 强转->string,并去掉多余空格
	 * 
	 * @param str
	 * @param defaultValue
	 * @return
	 */
	public static String toStr(Object str, String defaultValue) {
		if (null == str) {
			return defaultValue;
		}
		return str.toString().trim();
	}

	/**
	 * 强转->int
	 * 
	 * @param obj
	 * @return
	 */
	public static int toInt(Object value) {
		return toInt(value, -1);
	}

	/**
	 * 强转->int
	 * 
	 * @param obj
	 * @param defaultValue
	 * @return
	 */
	public static int toInt(Object value, int defaultValue) {
		return ConvertUtil.toInt(value, defaultValue);
	}

	/**
	 * 强转->long
	 * 
	 * @param obj
	 * @return
	 */
	public static long toLong(Object value) {
		return toLong(value, -1);
	}

	/**
	 * 强转->long
	 * 
	 * @param obj
	 * @param defaultValue
	 * @return
	 */
	public static long toLong(Object value, long defaultValue) {
		return ConvertUtil.toLong(value, defaultValue);
	}

	// public static String encodeUrl(String url) {
	// return URLKit.encode(url, CharsetKit.UTF_8);
	// }
	//
	// public static String decodeUrl(String url) {
	// return URLKit.decode(url, CharsetKit.UTF_8);
	// }

	/**
	 * map的key转为小写
	 * 
	 * @param map
	 * @return Map<String,Object>
	 */

	public static Map<String, Object> caseInsensitiveMap(Map<String, Object> map) {
		Map<String, Object> tempMap = new HashMap<>();
		for (String key : map.keySet()) {
			tempMap.put(key.toLowerCase(), map.get(key));
		}
		return tempMap;
	}

	/**
	 * 获取map中第一个数据值
	 * 
	 * @param <K>
	 *            Key的类型
	 * @param <V>
	 *            Value的类型
	 * @param map
	 *            数据源
	 * @return 返回的值
	 */
	public static <K, V> V getFirstOrNull(Map<K, V> map) {
		V obj = null;
		for (Entry<K, V> entry : map.entrySet()) {
			obj = entry.getValue();
			if (obj != null) {
				break;
			}
		}
		return obj;
	}

	/**
	 * 创建StringBuilder对象
	 * 
	 * @return StringBuilder对象
	 */
	public static StringBuilder builder(String... strs) {
		final StringBuilder sb = new StringBuilder();
		for (String str : strs) {
			sb.append(str);
		}
		return sb;
	}

	/**
	 * 创建StringBuilder对象
	 * 
	 * @return StringBuilder对象
	 */
	public static void builder(StringBuilder sb, String... strs) {
		for (String str : strs) {
			sb.append(str);
		}
	}

	/**
	 * 去掉指定后缀
	 * 
	 * @param str
	 *            字符串
	 * @param suffix
	 *            后缀
	 * @return 切掉后的字符串，若后缀不是 suffix， 返回原字符串
	 */
	public static String removeSuffix(String str, String suffix) {
		if (isEmpty(str) || isEmpty(suffix)) {
			return str;
		}
		if (str.endsWith(suffix)) {
			return str.substring(0, str.length() - suffix.length());
		}
		return str;
	}

	/**
	 * 当前时间
	 * 
	 * @author stylefeng
	 * @Date 2017/5/7 21:56
	 */
	// public static String currentTime(){
	// return DateUtil.getTime();
	// }
	/**
	 * 首字母大写
	 * 
	 * @author stylefeng
	 * @Date 2017/5/7 22:01
	 */
	public static String firstLetterToUpper(String val) {
		return StrKit.firstCharToUpperCase(val);
	}

	/**
	 * 首字母小写
	 * 
	 * @author stylefeng
	 * @Date 2017/5/7 22:02
	 */
	public static String firstLetterToLower(String val) {
		return StrKit.firstCharToLowerCase(val);
	}

	/**
	 * 判断是否是windows操作系统
	 * 
	 * @author stylefeng
	 * @Date 2017/5/24 22:34
	 */
	public static Boolean isWinOs() {
		String os = System.getProperty("os.name");
		if (os.toLowerCase().startsWith("win")) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 获取临时目录
	 * 
	 * @author stylefeng
	 * @Date 2017/5/24 22:35
	 */
	public static String getTempPath() {
		return System.getProperty("java.io.tmpdir");
	}
	
	public static void main(String[] args) {
		System.out.println(RandomUtil.createRandomWithLength(5));
		System.out.println(RandomUtil.createRandomFromString("adfasdfasdf", 2));
	}
}
